# -*- coding:utf-8 -*-

from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.dao.search_task_dao import SearchTaskDao, OrderRecordDao
from module_admin.entity.do.search_task_do import SearchTask
from module_admin.entity.do.order_record_do import OrderRecord
from module_admin.entity.vo.search_task_vo import (
    SearchTaskModel,
    SearchTaskQueryModel,
    SearchTaskCreateModel,
    SearchTaskUpdateModel,
    OrderRecordModel,
    OrderRecordQueryModel
)
from typing import List, Dict, Any, Optional
from datetime import datetime
import json
from utils.log_util import logger


class SearchTaskService:
    """搜索任务业务逻辑层"""
    
    @classmethod
    async def get_task_list(
        cls,
        db: AsyncSession,
        query_params: SearchTaskQueryModel,
        page_num: int = 1,
        page_size: int = 10,
        current_user_id: int = None,
        is_admin: bool = False,
        filter_user_id: int = None  # 超级管理员切换用户查看（可选）
    ) -> Dict:
        """获取任务列表（支持用户隔离）
        
        Args:
            db: 数据库会话
            query_params: 查询参数
            page_num: 页码
            page_size: 每页数量
            current_user_id: 当前用户ID
            is_admin: 是否是管理员（role_id=1的超级管理员）
            filter_user_id: 超级管理员切换用户查看（可选，仅管理员可用）
        """
        tasks, total = await SearchTaskDao.get_task_list(
            db, query_params, page_num, page_size,
            current_user_id=current_user_id,
            is_admin=is_admin,
            filter_user_id=filter_user_id
        )
        
        task_list = [SearchTaskModel.model_validate(task) for task in tasks]
        
        return {
            "rows": task_list,
            "total": total
        }
    
    @classmethod
    async def get_task_detail(cls, db: AsyncSession, task_id: int) -> SearchTaskModel:
        """获取任务详情"""
        task = await SearchTaskDao.get_task_by_id(db, task_id)
        if task:
            return SearchTaskModel.model_validate(task)
        return None
    
    @classmethod
    async def manual_search(
        cls,
        db: AsyncSession,
        search_config: dict,
        user_id: int = None
    ) -> Dict[str, Any]:
        """
        手动搜索
        选择任意一个在线、状态正常的搜索账号执行一次搜索
        
        Args:
            db: 数据库会话
            search_config: 搜索配置 {keyword, min_price, max_price}
            user_id: 执行搜索的用户ID（用于WebSocket推送过滤）
        
        Returns:
            搜索结果
        """
        from tcp_server.tcp_clients import ClientManager
        from module_admin.service.agent_client_service import AgentClientService
        from module_admin.dao.agent_client_dao import AgentClientDao
        from module_admin.entity.vo.agent_client_vo import AgentClientModel
        from utils.log_util import logger
        
        keyword = search_config.get('keyword', '').strip()
        if not keyword:
            return {
                "success": False,
                "msg": "搜索关键词不能为空"
            }
        
        # 1. 选择可用的搜索客户端（在线、状态正常）
        # ✅ 优先使用搜索类型的客户端
        search_clients = await AgentClientService.get_available_search_clients(db)
        
        # ✅ 过滤出在线且状态正常的搜索客户端
        available = [
            c for c in search_clients
            if c.online_status == 'online' 
            and c.work_status in ['idle', 'searching']  # 空闲或正在搜索都可以
        ]
        
        # ✅ 如果没有搜索类型的客户端，尝试使用下单类型的客户端（只要在线且状态正常）
        if not available:
            order_clients = await AgentClientDao.get_clients_by_type(db, 'order', require_login=False)
            order_models = [
                AgentClientModel.model_validate(client) 
                for client in order_clients 
                if client.online_status == 'online'
                and (client.work_status or 'idle') in ['idle', 'searching']
                and (client.work_status or 'idle') != 'banned'  # 排除被封禁的账号
                and (client.work_status or 'idle') != 'error'    # 排除异常状态的账号
            ]
            if order_models:
                logger.info(f"手动搜索：没有可用的搜索账号，使用 {len(order_models)} 个下单账号进行搜索")
                available = order_models
        
        if not available:
            return {
                "success": False,
                "msg": "没有可用的搜索客户端（需要在线且状态正常）"
            }
        
        # 选择第一个可用客户端（可以后续优化为负载均衡）
        search_client = available[0]
        
        # 2. 发送搜索命令
        # ✅ 包含user_id，确保搜索结果推送给正确的用户
        search_cmd = {
            "event": "search",
            "direction": "req",
            "success": True,
            "code": 0,
            "msg": "",
            "data": {
                "client_id": search_client.client_id,
                "keyword": keyword,
                "min_price": float(search_config.get('min_price', 0)),
                "max_price": float(search_config.get('max_price', 0)),
                "user_id": user_id  # ✅ 传递user_id，用于WebSocket推送过滤
            }
        }
        
        if user_id:
            logger.info(f"手动搜索：user_id={user_id}, keyword={keyword}, client_id={search_client.client_id}")
        else:
            logger.warning(f"⚠️ 手动搜索：user_id为None，搜索结果可能推送给错误的用户")
        
        try:
            # 发送搜索命令（异步，不等待结果，结果通过WebSocket推送）
            success = await ClientManager.send_to_client(search_client.client_id, search_cmd)
            
            if success:
                return {
                    "success": True,
                    "msg": "手动搜索命令已发送，搜索结果将通过WebSocket实时推送",
                    "data": {
                        "client_id": search_client.client_id,
                        "keyword": keyword
                    }
                }
            else:
                return {
                    "success": False,
                    "msg": "发送搜索命令失败，客户端可能已离线"
                }
                
        except Exception as e:
            logger.exception(f"手动搜索异常: {e}")
            return {
                "success": False,
                "msg": f"搜索异常: {str(e)}"
            }
    
    @classmethod
    async def create_task(
        cls,
        db: AsyncSession,
        create_data: SearchTaskCreateModel,
        create_by: int,
        dept_id: int
    ) -> SearchTaskModel:
        """创建搜索任务"""
        task = SearchTask(
            task_name=create_data.task_name,
            keyword=create_data.keyword,
            total_time=create_data.total_time,
            auto_order=create_data.auto_order,
            remark=create_data.remark,
            task_status='stopped',
            search_count=0,
            status='0',
            create_by=create_by,
            dept_id=dept_id
        )
        
        created_task = await SearchTaskDao.create_task(db, task)
        return SearchTaskModel.model_validate(created_task)
    
    @classmethod
    async def update_task(
        cls,
        db: AsyncSession,
        task_id: int,
        update_data: SearchTaskUpdateModel
    ):
        """更新任务"""
        update_dict = update_data.model_dump(exclude_unset=True)
        if update_dict:
            await SearchTaskDao.update_task(db, task_id, update_dict)
    
    @classmethod
    async def delete_task(cls, db: AsyncSession, task_id: int):
        """删除任务"""
        await SearchTaskDao.delete_task(db, task_id)
    
    @classmethod
    async def start_task(cls, db: AsyncSession, task_id: int):
        """启动任务"""
        update_data = {'task_status': 'running'}
        await SearchTaskDao.update_task(db, task_id, update_data)
    
    @classmethod
    async def stop_task(cls, db: AsyncSession, task_id: int):
        """停止任务"""
        update_data = {'task_status': 'stopped'}
        await SearchTaskDao.update_task(db, task_id, update_data)
    
    @classmethod
    async def get_running_tasks(cls, db: AsyncSession) -> List[SearchTaskModel]:
        """获取运行中的任务"""
        tasks = await SearchTaskDao.get_running_tasks(db)
        return [SearchTaskModel.model_validate(task) for task in tasks]
    
    @classmethod
    async def update_search_count(cls, db: AsyncSession, task_id: int):
        """更新搜索次数"""
        update_data = {
            'last_search_time': datetime.now()
        }
        # 这里可以用原生SQL增加计数，简化版先不处理
        await SearchTaskDao.update_task(db, task_id, update_data)
    
    @classmethod
    async def save_current_config(cls, db: AsyncSession, user_id: int, config: dict) -> Dict:
        """
        保存当前用户的搜索任务配置
        使用 remark 字段存储 JSON 格式的完整配置
        """
        try:
            import json
            from sqlalchemy import select
            
            # 查找或创建当前用户的配置任务（使用特殊 task_name）
            task_name = f"__user_config_{user_id}__"
            query = select(SearchTask).where(
                SearchTask.task_name == task_name
            )
            result = await db.execute(query)
            existing_task = result.scalar_one_or_none()
            
            # 构建配置 JSON（包含所有前端需要的字段）
            config_json = json.dumps(config, ensure_ascii=False)
            
            if existing_task:
                # 更新现有任务
                existing_task.keyword = config.get('keyword', '')
                existing_task.total_time = config.get('total_time', 60)
                existing_task.auto_order = '1' if config.get('enable_auto_order', False) else '0'
                existing_task.skip_first_search = '1' if config.get('skip_first_search', False) else '0'  # ✅ 首次搜索不自动下单
                existing_task.enable_jitter = '1' if config.get('enable_jitter', True) else '0'  # ✅ 抖动搜索（默认开启）
                existing_task.remark = config_json
                existing_task.update_by = str(user_id)
                existing_task.update_time = datetime.now()
            else:
                # 创建新任务
                new_task = SearchTask(
                    task_name=task_name,
                    keyword=config.get('keyword', ''),
                    total_time=config.get('total_time', 60),
                    auto_order='1' if config.get('enable_auto_order', False) else '0',
                    skip_first_search='1' if config.get('skip_first_search', False) else '0',  # ✅ 首次搜索不自动下单
                    enable_jitter='1' if config.get('enable_jitter', True) else '0',  # ✅ 抖动搜索（默认开启）
                    remark=config_json,
                    task_status='stopped',
                    search_count=0,
                    status='0',
                    create_by=str(user_id),
                    dept_id=1  # 默认部门
                )
                db.add(new_task)
            
            await db.commit()
            
            return {
                'success': True,
                'msg': '配置已保存',
                'data': config
            }
        except Exception as e:
            await db.rollback()
            logger.exception(e)
            return {
                'success': False,
                'msg': f'保存配置失败: {str(e)}'
            }
    
    @classmethod
    async def get_current_config(cls, db: AsyncSession, user_id: int) -> Dict:
        """
        获取当前用户的搜索任务配置
        """
        try:
            import json
            from sqlalchemy import select
            
            # 查找当前用户的配置任务
            task_name = f"__user_config_{user_id}__"
            query = select(SearchTask).where(
                SearchTask.task_name == task_name
            )
            result = await db.execute(query)
            task = result.scalar_one_or_none()
            
            if task and task.remark:
                # 从 remark 字段解析配置
                try:
                    config = json.loads(task.remark)
                    return {
                        'success': True,
                        'msg': '获取配置成功',
                        'data': config
                    }
                except json.JSONDecodeError:
                    # 如果解析失败，尝试从任务字段构建基本配置
                    config = {
                        'keyword': task.keyword or '',
                        'total_time': task.total_time or 60,
                        'enable_auto_order': task.auto_order == '1',
                        'skip_first_search': task.skip_first_search == '1',
                        'enable_jitter': task.enable_jitter == '1' if hasattr(task, 'enable_jitter') and task.enable_jitter else True,
                        'min_price': None,
                        'max_price': None,
                        'order_price': 0,
                        'display_count': 30
                    }
                    return {
                        'success': True,
                        'msg': '获取配置成功（部分字段）',
                        'data': config
                    }
            else:
                # 没有找到配置
                return {
                    'success': False,
                    'msg': '未找到保存的配置',
                    'data': None
                }
        except Exception as e:
            logger.exception(e)
            return {
                'success': False,
                'msg': f'获取配置失败: {str(e)}',
                'data': None
            }
    
    @classmethod
    async def get_recent_results(
        cls, 
        db: AsyncSession, 
        keyword: Optional[str] = None, 
        limit: int = 30,
        user_id: Optional[int] = None,
        is_admin: bool = False
    ) -> Dict:
        """
        获取最新的搜索结果（从数据库）
        优先从 search_record 表查询最新记录
        
        Args:
            db: 数据库会话
            keyword: 搜索关键词，不传则返回所有关键词的最新结果
            limit: 返回数量，默认30
            user_id: 用户ID，用于过滤搜索结果（用户隔离）
            is_admin: 是否是管理员
        """
        try:
            from sqlalchemy import select, desc
            from module_admin.entity.do.search_record_do import SearchRecord
            
            # 构建查询
            query = select(SearchRecord).where(
                SearchRecord.del_flag == '0'
            )
            
            # ✅ 用户隔离：非管理员只能看到自己的搜索结果
            # 管理员如果指定了user_id，则查看指定用户的搜索结果
            if not is_admin and user_id:
                # 非管理员：只查看自己的搜索结果
                query = query.where(SearchRecord.create_by == user_id)
            elif is_admin and user_id:
                # 管理员查看指定用户的搜索结果
                query = query.where(SearchRecord.create_by == user_id)
            # 如果is_admin=True但user_id=None，则查看所有用户的搜索结果（管理员查看全部）
            
            # 如果指定了关键词，则过滤
            if keyword:
                query = query.where(SearchRecord.search_keyword == keyword)
            
            # ✅ 按发布时间倒序，限制数量（按发布时间排序最准确，显示最新发布的商品）
            # first_found_time: 首次发现时间（用于统计：商品第一次被发现的时间）
            # last_found_time: 最后发现时间（用于追踪：商品最近一次出现在搜索结果中的时间）
            # publish_time: 发布时间（商品的真实发布时间，用于排序和判断新商品）
            # 注意：应该按 publish_time 排序，因为这是商品的真实发布时间，更能反映商品的"新鲜度"
            query = query.order_by(desc(SearchRecord.publish_time)).limit(limit)
            
            result = await db.execute(query)
            records = result.scalars().all()
            
            # 转换为前端需要的格式
            results = []
            for record in records:
                # 构建商品数据（直接使用 SearchRecord 的字段）
                item = {
                    'id': record.item_id,
                    'item_id': record.item_id,
                    'itemId': record.item_id,
                    'title': record.title or '',
                    'price': float(record.price) if record.price else 0,
                    'image_url': record.image_url or '',
                    'picUrl': record.image_url or '',  # 兼容前端字段名
                    'seller_id': record.seller_id or '',
                    'seller_nick': record.seller_nick or '',
                    'location': record.location or '',
                    'publish_time': record.publish_time or 0,
                    'publishTime': record.publish_time or 0,  # 兼容前端字段名
                    'position': record.position if record.position is not None else 0,
                    'tagname': record.tag_name or '',  # ✅ 添加标签字段
                    'tagName': record.tag_name or '',  # 兼容前端字段名
                    'keyword': record.search_keyword or keyword or '',
                    'is_new': bool(record.is_new) if record.is_new is not None else False,
                    'is_ordered': False,  # 需要从订单表查询
                    'search_time': record.last_found_time.strftime('%Y-%m-%d %H:%M:%S') if record.last_found_time else ''
                }
                results.append(item)
            
            return {
                'success': True,
                'msg': f'获取到 {len(results)} 条搜索结果',
                'data': {
                    'results': results,
                    'keyword': keyword,
                    'total': len(results),
                    'timestamp': datetime.now().isoformat()
                }
            }
        except Exception as e:
            logger.exception(e)
            # 如果表不存在或其他错误，返回空结果
            return {
                'success': False,
                'msg': f'获取搜索结果失败: {str(e)}',
                'data': {
                    'results': [],
                    'keyword': keyword,
                    'total': 0
                }
            }



class OrderRecordService:
    """下单记录业务逻辑层"""
    
    @classmethod
    async def get_order_list(
        cls,
        db: AsyncSession,
        query_params: OrderRecordQueryModel,
        page_num: int = 1,
        page_size: int = 10,
        current_user_id: int = None,
        is_admin: bool = False,
        filter_user_id: int = None  # 超级管理员切换用户查看（可选）
    ) -> Dict:
        """获取下单记录列表（支持用户隔离）
        
        Args:
            db: 数据库会话
            query_params: 查询参数
            page_num: 页码
            page_size: 每页数量
            current_user_id: 当前用户ID
            is_admin: 是否是管理员（role_id=1的超级管理员）
            filter_user_id: 超级管理员切换用户查看（可选，仅管理员可用）
        """
        records, total = await OrderRecordDao.get_record_list(
            db, query_params, page_num, page_size,
            current_user_id=current_user_id,
            is_admin=is_admin,
            filter_user_id=filter_user_id
        )
        
        record_list = [OrderRecordModel.model_validate(record) for record in records]
        
        return {
            "rows": record_list,
            "total": total
        }
    
    @classmethod
    async def create_order_record(
        cls,
        db: AsyncSession,
        search_item: dict,  # SearchItem数据（商品信息）
        account_user_id: str,  # 账号用户ID
        user_name: str,  # 账号昵称
        order_result: dict,  # CreateOrderResponseDto数据（订单结果）
        client_id: str,  # 客户端ID
        create_by: int,
        dept_id: int,
        is_auto_order: bool = True  # ✅ 修复：添加is_auto_order参数，默认为True（自动下单）
    ) -> OrderRecordModel:
        """
        创建下单记录（按照C# OrderService.AddHistoryOrder逻辑）
        
        Args:
            search_item: 搜索商品数据（SearchItem），包含所有商品信息
            account_user_id: 账号用户ID（对应C#的account.UserId）
            user_name: 账号昵称（对应C#的account.NickName）
            order_result: 下单结果（CreateOrderResponseDto），包含bizOrderId, payOrderId, payUrl等
            client_id: 客户端ID
            create_by: 创建者
            dept_id: 部门ID
        """
        # ✅ 按照C#逻辑：从SearchItem复制所有字段，然后添加订单结果和账号信息
        # 转换 price 字符串为 DECIMAL（如果可能）
        price_decimal = None
        price_str = search_item.get("price") or search_item.get("Price") or ""
        if price_str:
            try:
                price_decimal = float(price_str)
            except (ValueError, TypeError):
                price_decimal = None
        
        record = OrderRecord(
            # 商品信息（来自SearchItem）
            item_id=search_item.get("item_id") or search_item.get("itemId") or search_item.get("ItemId") or "",
            title=search_item.get("title") or search_item.get("Title") or "",
            price=price_decimal,
            pic_url=search_item.get("pic_url") or search_item.get("picUrl") or search_item.get("PicUrl") or "",
            pic_width=cls._parse_int(search_item.get("pic_width") or search_item.get("picWidth") or search_item.get("PicWidth")),
            pic_height=cls._parse_int(search_item.get("pic_height") or search_item.get("picHeight") or search_item.get("PicHeight")),
            
            # 卖家信息（来自SearchItem）
            tag_name=search_item.get("tag_name") or search_item.get("tagName") or search_item.get("TagName") or "",
            seller_id=search_item.get("seller_id") or search_item.get("sellerId") or search_item.get("SellerId") or "",
            user_nick_name=search_item.get("user_nick_name") or search_item.get("userNickName") or search_item.get("UserNickName") or "",
            user_avatar_url=search_item.get("user_avatar_url") or search_item.get("userAvatarUrl") or search_item.get("UserAvatarUrl") or "",
            area=search_item.get("area") or search_item.get("Area") or "",
            hide_user_info=cls._parse_bool(search_item.get("hide_user_info") or search_item.get("hideUserInfo") or search_item.get("HideUserInfo")),
            
            # 搜索信息（来自SearchItem）
            keyword=search_item.get("keyword") or search_item.get("Keyword") or "",
            page=cls._parse_int(search_item.get("page") or search_item.get("Page"), default=1),
            position=cls._parse_int(search_item.get("position") or search_item.get("Position")),
            publish_time=cls._parse_datetime(search_item.get("publish_time") or search_item.get("publishTime") or search_item.get("PublishTime")),
            search_time=cls._parse_datetime(search_item.get("search_time") or search_item.get("searchTime") or search_item.get("SearchTime")),
            
            # 商品属性（来自SearchItem）
            is_alimama_ad=cls._parse_bool(search_item.get("is_alimama_ad") or search_item.get("isAliMaMaAD") or search_item.get("IsAliMaMaAD")),
            is_auction=cls._parse_bool(search_item.get("is_auction") or search_item.get("isAuction") or search_item.get("IsAuction")),
            
            # 下单信息（来自Account和client_id）
            client_id=client_id,
            account_user_id=account_user_id,  # 对应C#的AccountUserId
            user_name=user_name,  # 对应C#的UserName
            
            # 订单信息（来自CreateOrderResponseDto）
            biz_order_id=order_result.get("bizOrderId") or order_result.get("biz_order_id") or "",
            biz_order_id_str=order_result.get("bizOrderIdStr") or order_result.get("biz_order_id_str") or "",
            pay_order_id=order_result.get("payOrderId") or order_result.get("pay_order_id") or "",
            pay_url=order_result.get("payUrl") or order_result.get("pay_url") or "",
            service_order=order_result.get("serviceOrder") or order_result.get("service_order") or "",
            use_pay_url=order_result.get("usePayUrl") or order_result.get("use_pay_url") or "",
            
            # 状态信息
            order_status='ordered',  # 已下单待支付（对应C#创建时状态）
            is_auto_order=is_auto_order,  # ✅ 修复：使用传入的参数，而不是硬编码为True
            
            # BaseMixin字段
            create_by=create_by,
            dept_id=dept_id
            # create_time 和 update_time 由BaseMixin自动设置
        )
        
        created_record = await OrderRecordDao.create_record(db, record)
        
        return OrderRecordModel.model_validate(created_record)
    
    @staticmethod
    def _parse_int(value, default=None):
        """解析整数"""
        if value is None:
            return default
        try:
            return int(value)
        except (ValueError, TypeError):
            return default
    
    @staticmethod
    def _parse_bool(value, default=False):
        """解析布尔值"""
        if value is None:
            return default
        if isinstance(value, bool):
            return value
        if isinstance(value, str):
            return value.lower() in ('true', '1', 'yes', 'on')
        return bool(value)
    
    @staticmethod
    def _parse_datetime(value):
        """解析日期时间"""
        if not value:
            return None
        try:
            from datetime import datetime
            if isinstance(value, datetime):
                return value
            if isinstance(value, str):
                # 尝试解析常见格式
                for fmt in ['%Y-%m-%d %H:%M:%S', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%d']:
                    try:
                        return datetime.strptime(value, fmt)
                    except ValueError:
                        continue
        except Exception:
            pass
        return None
    
    @classmethod
    async def manual_order(
        cls,
        db: AsyncSession,
        item_data: dict,
        allow_search_accounts: bool = False,
        create_by: int = 1,
        dept_id: int = 1
    ) -> Dict[str, Any]:
        """
        手动下单
        
        Args:
            db: 数据库会话
            item_data: 商品数据（包含item_id, title, price等）
            allow_search_accounts: 是否允许使用搜索账号下单（临时方案）
            create_by: 创建者ID
            dept_id: 部门ID
        
        Returns:
            下单结果
        """
        import asyncio
        from tcp_server.tcp_clients import ClientManager
        from module_admin.service.agent_client_service import AgentClientService
        from utils.log_util import logger
        
        # 1. 选择可用的下单客户端
        order_clients = await AgentClientService.get_available_order_clients(
            db, 
            allow_search_accounts=allow_search_accounts
        )
        
        # ✅ 过滤：只选择在线、有默认地址、空闲且未被封禁的客户端
        available = [
            c for c in order_clients
            if c.online_status == 'online' 
            and (c.default_address_id or '').strip()
            and (c.work_status or 'idle') == 'idle'  # ✅ 只选择空闲状态的agent，防止并发下单
        ]
        
        if not available:
            # ✅ 根据是否有账号类型给出更明确的提示
            if not allow_search_accounts and len(order_clients) == 0:
                return {
                    "success": False,
                    "msg": "没有可用的下单账号（请先配置下单账号）"
                }
            elif allow_search_accounts:
                # 检查是否有被封禁的账号
                banned_count = sum(1 for c in order_clients if (c.work_status or 'idle') == 'banned')
                if banned_count > 0:
                    return {
                        "success": False,
                        "msg": f"没有可用的下单账号（所有账号均被封禁或状态异常）"
                    }
                return {
                    "success": False,
                    "msg": "没有可用的下单账号（需要在线、有默认地址且未被封禁）"
                }
            else:
                return {
                    "success": False,
                    "msg": "没有可用的下单客户端（需要在线且有默认地址）"
                }
        
        # 选择第一个可用客户端（可以后续优化为负载均衡）
        order_client = available[0]
        
        item_id = item_data.get('item_id') or item_data.get('itemId') or item_data.get('id')
        if not item_id:
            return {
                "success": False,
                "msg": "缺少商品ID"
            }
        
        # 2. 检查是否已有pending订单（防止重复下单）
        from module_admin.dao.search_task_dao import OrderRecordDao
        existing_pending = await OrderRecordDao.get_pending_record_by_item_id(db, str(item_id))
        if existing_pending:
            return {
                "success": False,
                "msg": f"该商品正在下单中，请勿重复操作（订单ID: {existing_pending.id}）"
            }
        
        # 3. 创建pending订单记录（占位，防止并发）
        from module_admin.entity.do.order_record_do import OrderRecord
        pending_order = OrderRecord(
            item_id=str(item_id),
            title=item_data.get('title', ''),
            price=item_data.get('price'),
            client_id=order_client.client_id,
            order_status='pending',
            keyword=item_data.get('keyword', ''),
            seller_id=item_data.get('seller_id', ''),
            is_auto_order=False,  # ✅ 修复：手动下单标记为False
            create_by=create_by,
            dept_id=dept_id
        )
        await OrderRecordDao.create_record(db, pending_order)
        await db.commit()
        logger.info(f"✅ 已创建pending订单记录: item_id={item_id}, order_id={pending_order.id}, client_id={order_client.client_id}")
        
        # 4. 发送下单命令
        order_cmd = {
            "event": "order",
            "direction": "req",
            "success": True,
            "code": 0,
            "msg": "",
            "data": {
                "item_id": str(item_id),
                "address_id": order_client.default_address_id,
                "keyword": item_data.get('keyword', '')
            }
        }
        
        try:
            # 发送下单命令（异步，不等待结果，结果通过WebSocket推送）
            success = await ClientManager.send_to_client(order_client.client_id, order_cmd)
            
            if success:
                # 下单命令已发送，结果将通过WebSocket推送给前端
                # 注意：由于是异步处理，这里无法立即获得下单结果
                # 下单成功/失败的结果会通过WebSocket的client_response事件推送给前端
                return {
                    "success": True,
                    "msg": "下单命令已发送，请等待处理结果（结果将通过WebSocket推送）",
                    "data": {
                        "client_id": order_client.client_id,
                        "item_id": item_id,
                        "order_record_id": pending_order.id
                    }
                }
            else:
                # 发送失败，删除pending订单
                await OrderRecordDao.delete_record(db, pending_order.id)
                await db.commit()
                logger.error(f"❌ 发送下单命令失败，已删除pending订单: order_id={pending_order.id}")
                return {
                    "success": False,
                    "msg": "发送下单命令失败，客户端可能已离线"
                }
                
        except Exception as e:
            logger.exception(f"手动下单异常: {e}")
            return {
                "success": False,
                "msg": f"下单异常: {str(e)}"
            }
    
    @classmethod
    async def update_order_status(
        cls,
        db: AsyncSession,
        record_id: int,
        status: str,
        result_data: dict = None,
        error_msg: str = None
    ):
        """更新下单状态"""
        update_data = {'order_status': status}
        if result_data:
            update_data['order_result'] = json.dumps(result_data, ensure_ascii=False)
        if error_msg:
            update_data['error_msg'] = error_msg
        
        await OrderRecordDao.update_record(db, record_id, update_data)

